第14章 コンポーネントの結合
コンポーネントの関連について
開発の利便性と設計とのトレードオフ
依存性管理の指標
I, A, D
非循環依存関係の原則(ADP)
二日酔い症候群へのソリューション
安定版をビルドできない状態が何週間も続く
週次ビルドはうまく機能しない(どんどん期間が伸びていく)
開発環境をリリース可能なコンポーネントに分割する
コンポーネントが作業単位
リリース番号を割り当てる
再利用・リリース等価 & 全再利用
依存関係のグラフからリリース手順
一番下のノード(何にも依存していない)からリリース
コンポーネントの依存関係を把握できているからこそ、システムをビルドする方法が明確なのだ。(Kindle の位置No.1870)
グラフから影響範囲も分かる
循環依存してしまうとリリースが難しくなる
事実上一つの巨大コンポーネント(密結合)
循環依存の解消
依存関係逆転の原則
インターフェイス
循環依存する両者が依存する新しいコンポーネント
アプリケーションの構造は変化する
循環依存は常に注視する
トップダウンの設計
コンポーネントの構造をトップダウンで設計するのは不可能 (Kindle の位置No.1917-1918)
コンポーネントがシステムの何らかの機能を表しているわけではない
ビルド可能性や保守性を見る地図
依存関係の把握
コンポーネントの依存構造は、システムの論理設計に合わせて育てていく
価値の高い安定したコンポーネントを、頻繁に変更されるコンポーネントから保護するのだ。(Kindle の位置No.1935)
安定依存の原則(SDP)
安定度とは、簡単には変更できないこと(stableの定義から)
ソフトウェアを変更しづらくするには、多数のソフトウェアコンポーネントから依存されるようにすればいい。(Kindle の位置No.1962-1963)
例:3つのコンポーネントから依存されたx(図14-5)
xは安定したコンポーネント
=xは3つのコンポーネントに対する責務を負っている
xは他のコンポーネントに依存していないので独立
例:3つのコンポーネントに依存したy(図14-6)
yは不安定なコンポーネント
外部要因による変更の可能性(従属)
(図では(不安定な)yに依存するコンポーネントはない。責務を負っていない)
指標 I(不安定さ)= ファン・アウト / (ファン・イン + ファン・アウト)
Xでは 0 / (3 + 0)
yでは 3 / (0 + 3)
安定依存の原則(SDP)は、コンポーネントのIを依存するコンポーネントのIよりも大きくすべきというものである。(Kindle の位置No.2012-2013)
(Iが大きい=不安定)
安定度の高いコンポーネントもあれば、安定度の低いコンポーネントもあるようにしておきたい。(Kindle の位置No.2017-2018)
図14-8
これを実現するために依存関係逆転の原則の例(図14-10, 14-11)
抽象コンポーネント
インターフェイスしかないコンポーネント
安定度が非常に高い
(従属しなさそう)
RubyやPythonには存在しないとのこと
依存関係を逆転させるときに、何らかの宣言をしたりインターフェイスを継承したりする必要がない (Kindle の位置No.2057-2058)
安定度・抽象度等価の原則(SAP)
上位レベルの方針を、安定度の高い(I=0)コンポーネントに配置したい
オープン・クローズドの原則
既存コードを変更せずに拡張できる -> 抽象クラス
コンポーネントの安定度を高くしようと思えば、拡張できるようにインターフェイスと抽象クラスで構成すべき (Kindle の位置No.2077-2078)
SAPとSDPの組み合わせが、コンポーネント版の依存関係逆転の原則
抽象度が高くなる方向に依存する
(抽象度が高い=インターフェイスや抽象クラス)
指標 A:コンポーネント内のクラスのうち、抽象クラスとインターフェイスの数の割合
0ならば抽象クラスとインターフェイスが一切無い
1ならば抽象クラスとインターフェイスのみ
安定度 I と抽象度 A の関連
図14-13
I=0, A=1 と I=1, A=0 を結ぶ直線が主系列
依存するコンポーネントだけ(=安定)の抽象
依存するコンポーネントがない(=不安定)具象
I=0, A=0:安定度が最高の具象コンポーネント
柔軟性に欠ける
変動性が大きいコンポーネントでは苦痛
I=1, A=1:最大限抽象化されているが、依存するコンポーネントがない
使われていないので、無意味
主系列からの距離(TODO)
散布図
主系列への適合度